<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <link href="/static/js/bootstrap.min.css" rel="stylesheet">
    <title data-en="Voice Clone - Speak with Any Voice" data-cn="语音克隆-用任意声音说话"></title>
    <style>
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        }

        .container {
            max-width: 1340px;
            margin: 20px auto 50px;
        }

        .custom-alert {
            background-color: #f8d7da;
            border-color: #f5c6cb;
            color: #721c24;
            border-radius: .25rem;
            padding: 1rem;
            margin-bottom: 20px;
        }

        .custom-alert h4 {
            color: #721c24;
        }

        .custom-alert hr {
            border-color: #f5c6cb;
        }

        .form-label {
            font-size: 1rem;
            font-weight: bold;
            color: #0d6efd;
        }

        .form-control {
            border-radius: .25rem;
            margin-top: .5rem;
        }

        .form-text {
            font-size: 0.875rem;
            color: #6c757d;
        }

        .form-select {
            height: calc(2.5rem + 2px);
        }

        .btn-file {
            position: relative;
            overflow: hidden;
        }

        .btn-file input[type=file] {
            position: absolute;
            top: 0;
            right: 0;
            margin: 0;
            padding: 0;
            font-size: 20px;
            cursor: pointer;
            opacity: 0;
            filter: alpha(opacity=0);
        }

        .btn-record {
            margin-right: 10px;
        }


        .btn-secondary-srt {
            margin-right: 10px;
            position: relative;
        }

        .btn-secondary-srt input[type=file] {
            position: absolute;
            top: 0;
            right: 0;
            margin: 0;
            padding: 0;
            font-size: 20px;
            cursor: pointer;
            opacity: 0;
            filter: alpha(opacity=0);
        }

        .text-danger {
            color: #dc3545;
        }

        #dropaudio {
            cursor: pointer
        }

        #dropaudio {
            border: 2px dashed #ccc;
            padding: 20px;
            text-align: center;
            cursor: pointer;
            background: #fff;
        }

        #dropaudio.dragover {
            background-color: #f0f0f0;
        }

        a.btn-link {
            text-decoration: none
        }
        .btn[data-status="on"]{
            color:#20c997;
            border-color: #20c997;
        }
        .btn[data-status="on"]:hover{
            background: #20c997;
            color: #fff;
        }
    </style>
</head>
<body>
<div class="container mb-2">
    <div class="alert  rounded-0" role="alert">
        <h4 class="alert-heading d-flex justify-content-between">
            <span class="text-danger" data-en="Voice Clone - Speak with Any Voice v{{ version }}"
                  data-cn="语音克隆-用任意声音说话! v{{ version }}"></span>
            <span>
                <a href="https://github.com/jianchang512/clone-voice/releases" target="_blank"
                   class="d-none fs-6 text-danger btn" id="checkupdate"></a>
			<a class="fs-6 text-black btn" href="https://github.com/jianchang512/clone-voice" target="_blank">Github</a>
			<a class="fs-6 text-black btn" href="https://github.com/jianchang512/clone-voice/issue" target="_blank"
               data-en="Post a Issue" data-cn="遇到问题?"></a>
			<a class="fs-6 text-success btn" href="javascript:;" onclick="showjz(this)"
               data-href="https://github.com/jianchang512/pyvideotrans/issues/80"
               data-en="Donate to the project" data-cn="捐助该项目"></a>
			</span>
        </h4>
        <hr>
        <div>
            <p class="mb-0" data-en="Record an audio segment with your own voice or using any tone"
               data-cn="用自己的声音或使用任意音色录制一段音频"></p>
            <p class="mb-0"
               data-en="The optimal audio material duration for cloning is 30-120s, ensuring clear and accurate vocals without any noise or background noise"
               data-cn="用于克隆的最佳音频素材时长为 30s-120s，确保清晰准确的人声，不要有杂音、背景音"></p>
        </div>
    </div>
    <div class="my-2 btn-group">
        <button onclick="toggle(this,'tts')" for="textInput" class="btn border btn-primary" data-en="Text ->Speech"
                data-cn="文字->声音"></button>
        <button onclick="toggle(this,'sts')" for="textInput" class="btn border" data-en="Speech ->Speech"
                data-cn="声音->声音"></button>
    </div>
    <div class="p-3 shadow bg-white">
        <div id="model_list" class="btn-group overflow-auto w-100 p-1" style="white-space: nowrap">
<!--模型列表同时而已作为-->

        </div>
        <div id="tts-area">
            <div class="row mt-4">
                <div class="col-md-3">
                    <div class="d-flex align-items-center">
                     <label for="model" class="form-label w-auto" data-en="Model:" data-cn="使用模型："></label>
                        <select onchange="set_voice(this)" class="form-select w-auto" name="model" id="model">
                            <option value="default" data-cn="默认" data-en="Default"></option>
                        </select>
                    </div>
                    <div class="d-flex align-items-center mt-1">
                    <label for="languageSelect" class="form-label w-auto" data-en="Language:" data-cn="文本语言："></label>

                    <select class="form-select w-auto" id="languageSelect">
                        <option data-en="Chinese" value="zh-cn" data-cn="中文"></option>
                        <option data-en="English" value="en" data-cn="英语"></option>
                        <option data-en="Japanese" value="ja" data-cn="日语"></option>
                        <option data-en="Korean" value="ko" data-cn="韩语"></option>
                        <option data-en="Spanish" value="es" data-cn="西班牙语"></option>
                        <option data-en="German" value="de" data-cn="德语"></option>
                        <option data-en="French" value="fr" data-cn="法语"></option>
                        <option data-en="Italian" value="it" data-cn="意大利语"></option>
                        <option data-en="Turkish" value="tr" data-cn="土耳其语"></option>
                        <option data-en="Russian" value="ru" data-cn="俄语"></option>
                        <option data-en="Portuguese" value="pt" data-cn="葡萄牙语"></option>
                        <option data-en="Polish" value="pl" data-cn="波兰语"></option>
                        <option data-en="Dutch" value="nl" data-cn="荷兰语"></option>
                        <option data-en="Arabic" value="ar" data-cn="阿拉伯语"></option>
                        <option data-en="Hungarian" value="hu" data-cn="匈牙利语"></option>
                        <option data-en="Czech" value="cs" data-cn="捷克语"></option>
                    </select>
                    </div>
                </div>
                <div class="col-md-3">
                    <label for="speed" class="form-label" data-en="Speed(0.1-2.0/1.0 is normal):"
                           data-cn="速度倍数(0.1-2.0/1.0=常速)："></label>
                    <div>
                        <input id="speed" name="speed" class="form-control mt-0" style="width:80px;" type="number"
                               min="0.1" max="2.0" step="0.05" value="1.0">
                    </div>
                </div>
                <div class="col-md-3">
                    <label for="audioSelect" class="form-label"><span data-en="The sound file to be used:"
                                                                      data-cn="要使用的声音文件:"></span><a href="javascript:;"
                                                                                                    onclick="shiting(this)"
                                                                                                    class="form-text"
                                                                                                    data-en="Train audition"
                                                                                                    data-cn="试听"></a></label>

                    <select class="form-select" id="audioSelect">
                    </select>
                    <div class="form-text">
                        <label class="btn btn-sm btn-secondary btn-file d-inline-block position-relative"><span
                                data-en="From Local Upload" data-cn="从本地上传"></span>
                            <input id="fileInput" type="file" accept="audio/wav, audio/mp3,audio/flac"
                                   class="position-absolute start-0 top-0 end-0 bottom-0 opacity-0"
                                   onchange="uploadFromLocal(this)"/>
                        </label>
                        <span data-en="Or record a 5-15s sound wave online, and you can choose to use it here"
                              data-cn="或在线录制5-15s的声音wav，即可在此选择使用"></span>
                    </div>
                </div>
                <div class="col-md-3">
                    <button class="btn btn-sm btn-primary btn-record" id="startRecord" data-en="start recording" data-cn="开始录制"></button>
                    <button class="btn btn-sm btn-danger btn-record" id="stopRecord" disabled data-en="stop recorder"
                            data-cn="停止录制"></button>
                    <button class="btn btn-sm btn-success btn-record" id="upload" disabled data-en="Use this recording"
                            data-cn="使用该录音"></button>
                    <audio class="mt-1" id="audioPlayer" controls></audio>
                </div>
            </div>

            <div class=" mt-4">
                            <textarea {% if not text_model %} disabled {% endif %} class="form-control d-block"
                                                              id="textInput" placeholder-cn="在此输入要合成的文字"
                                                              placeholder-en="input text in there" rows="5"></textarea>
                {% if text_model %}
                    <label class="btn-file  btn-secondary-srt">
                        <span class="btn btn-sm " data-en="Import SRT file" data-cn="导入srt文件"></span>
                        <input type="file" accept=".srt"
                               class="position-absolute start-0 top-0 end-0 bottom-0 opacity-0"
                               onchange="uploadsrt(this)">
                    </label>
                {% else %}
                    <div class="alert alert-danger my-2">
                                    <span data-en="The model needs to be downloaded before it can be used. If the source code is deployed, please execute the `python code_dev.py` download the model online, please go to the pre compiled version"
                                          data-cn="需要下载模型后才可使用，如果源码部署，请执行 python code_dev.py 在线下载模型，预编译版请去"></span>
                        <a href="https://github.com/jianchang512/clone-voice/releases/tag/v0.0.1"
                           target="_blank" data-en="Download model" data-cn="下载模型"></a>,<span
                            data-en="Unzip the tts folder in the current project directory, ensuring that the following three folders exist in the tts directory after decompression, and then restart the software"
                            data-cn="放到当前项目目录的 tts 文件夹下解压,确保解压后tts目录下存在如下3个文件夹，然后重启软件"></span> <img
                            class="d-block" src="/static/images/2.png" width="300">
                    </div>
                {% endif %}
            </div>
        </div>
        <div id="sts-area" class="d-none">
			<div class="p-2">
				<label for="audioSelect2" class="form-label">
					<span data-en="The sound file to be clone:" data-cn="要克隆的音色:"></span>
				</label>
				<select class="form-select d-inline-block w-auto" id="audioSelect2"></select>
			</div>
            <div>
                {% if voice_model %}
                    <div id="dropaudio" class=" border m-2 p-5 text-center "
                         data-en="Drag and drop or click  audio files here to upload"
                         data-cn="拖拽或点击将音频 wav/mp3/flac 文件上传">

                    </div>
                {% else %}
                    <div class="alert alert-danger my-2">
                                    <span data-en="The model needs to be downloaded before it can be used. If the source code is deployed, please execute the `python code_dev.py` download the model online, please go to the pre compiled version"
                                          data-cn="需要下载模型后才可使用，如果源码部署，请执行 python code_dev.py 在线下载模型，预编译版请去"></span>
                        <a href="https://github.com/jianchang512/clone-voice/releases/tag/v0.0.1"
                           target="_blank" data-en="Download model" data-cn="下载模型"></a>,<span
                            data-en="Unzip the tts folder in the current project directory, ensuring that the following three folders exist in the tts directory after decompression, and then restart the software"
                            data-cn="放到当前项目目录的 tts 文件夹下解压,确保解压后tts目录下存在如下3个文件夹，然后重启软件"></span> <img
                            class="d-block" src="/static/images/2.png" width="300">
                    </div>
                {% endif %}
				<div class="alert alert-danger d-none" id="sts_no"></div>
            </div>
        </div>

        <div class="row mt-4 mb-4">
            <div class="col-md-12 text-center">
                <audio id="downloadbtn" class="d-none" controls></audio>
            </div>
        </div>
        <div class="row mt-4">
            <div class="col-md-12 my-2 d-none text-danger text-center" id="nostart"></div>
            <div class="col-md-12 text-center position-relative">
                <button id="start_button" onclick="start(this)" class="btn btn-danger btn-start-record"
                        data-en="Start generating immediately" data-cn="立即开始生成"></button>
            </div>
            <div class="col-md-12 d-none text-danger text-center" id="tips"></div>
        </div>

    </div>
</div>
<script src="/static/js/jquery.min.js"></script>
<script src="/static/js/layer/layer.js"></script>
<script src="/static/js/bootstrap.bundle.min.js"></script>
<script>
    let language = '{{ language }}';
    let langlist = language === 'zh' ? {
        "lang1": '必须选择要试听的声音',
        "lang2": '录制中',
        "lang3": '停止录制后,可使用此按钮',
        'lang4': '已录制',
        'lang5': '开始录制',
        'lang6': '停止录制后,可使用此按钮',
        'lang7': '请选择要上传的文件',
        'lang8': '只可导入srt格式字幕文件',
        'lang9': '请选择一个srt文件',
        'lang10': "必须选择要使用的声音",
        'lang11': "必须输入要合成的文字",
        'lang12': '必须上传要转换的声音wav/mp3文件',
        'lang13': '开始合成，用时可能较久，耐心等待',
        'lang14': "[文字->声音]或[声音->声音]线程还没有启动完毕，请等待",
        'lang15': '已转为wav格式: ',
        'lang16': '速度必须在0.1--2.0之间，1为正常速度，2为两倍速',
        'lang17': '捐助该项目',
        'lang18': '如果项目对你有帮助，节省了时间和金钱，请考虑小额资助开发者，帮助项目能够长期保持更新和维护。',
        "lang19":"运行中",
        "lang20":"已停止"

    } : {

        "lang1": 'You must select the voice for audition',
        "lang2": 'Recording',
        "lang3": 'Use this button after stopping recording',
        'lang4': 'Recorded',
        'lang5': 'Start recording',
        'lang6': 'Use this button after stopping recording',
        'lang7': 'Please select a file to upload',
        'lang8': 'Only SRT subtitle files can be imported',
        'lang9': 'Please select an SRT file',
        'lang10': 'You must select a voice to use',
        'lang11': 'You must enter the text to be synthesized',
        'lang12': 'You must upload the wav/mp3 audio file for conversion',
        'lang13': 'The synthesis might take a while, please wait patiently',
        'lang14': "[text->speech] or [speech->speech] thread not started，hold on",
        'lang15': 'Convered to wav format: ',
        'lang16': 'speed between 0.1 and 2.0，1 is normal speed',
        'lang17': 'Donate to the project',
        'lang18': 'If the project is helpful to you, saving time and money, please consider providing small funding to developers help the project can be updated and maintained for a long time',
        'lang19':'Runing',
        'lang20':'Stoped'
    };
    let mediaRecorder;
    let audioChunks = [];
    let sec = 0;
    let timeid = null;
    const startRecordButton = document.getElementById('startRecord');
    const stopRecordButton = document.getElementById('stopRecord');
    const uploadButton = document.getElementById('upload');
    const audioPlayer = document.getElementById('audioPlayer');
    startRecordButton.addEventListener('click', startRecording);
    stopRecordButton.addEventListener('click', stopRecording);
    uploadButton.addEventListener('click', uploadRecording);

    function switch_language() {
        let type = language === 'zh' ? 'cn' : 'en';
        $(`[data-${type}]`).each(function () {
            $(this).text($(this).attr(`data-${type}`));
        });
        $('[placeholderen]').each(function () {
            $(this).attr('placeholder', $(this).attr(`placeholder-${type}`));
        });
    }
    // 更改启动停止状态
    function update_status(name,el){
        let status_new=$(el).attr('data-status')==='on'?'off':'on';
        let index=layer.load();
        $.post('/onoroff',{status_new:status_new,name:name},function (res){
            layer.close(index);
            console.log(res);
            if(res && res['code']===0){
                let t=status_new==='off'?`${name}/${language==='zh'?'已停止':'Stoped'}`:`${name}/${language==='zh'?'已启动':'Runing'}`;
                $(el).attr('data-status',status_new).text(t);
                $("#model").find(`option[value="${name}"]`).html(t)
                layer.msg(res['msg']);
            }else{
                layer.alert(res && res['msg']?res['msg']:"error",{title:false})
            }
        });
    }

    // 切换文字->声音，声音->声音
    function toggle(el, type) {
        $(el).addClass('btn-primary');
        $(el).siblings().removeClass('btn-primary');
        if (type == 'tts') {
            $("#sts-area").addClass('d-none');
            $("#tts-area").removeClass('d-none');
        } else {
            $("#sts-area").removeClass('d-none');
            $("#tts-area").addClass('d-none');
        }
    }

    // 试听声音
    function shiting(el) {
        let wavUrl = $('#audioSelect').val();
        if (!wavUrl) {
            return layer.alert(langlist['lang1'], {title: false})

        }
        // 创建 audio 元素
        var audio = new Audio('/static/voicelist/' + wavUrl);

        // 监听播放结束事件，删除 audio 元素
        audio.addEventListener('ended', function () {
            document.body.removeChild(audio);
        });

        // 将 audio 元素添加到 body 中
        document.body.appendChild(audio);

        // 播放音频
        audio.play();
    }

    // 启动录音
    function startRecording() {
        audioChunks = [];
        navigator.mediaDevices.getUserMedia({audio: true})
            .then(stream => {
                mediaRecorder = new MediaRecorder(stream);
                mediaRecorder.ondataavailable = event => {
                    if (event.data.size > 0) {
                        audioChunks.push(event.data);
                    }
                };
                mediaRecorder.onstop = () => {
                    const audioBlob = new Blob(audioChunks, {type: 'audio/wav'});
                    const audioUrl = URL.createObjectURL(audioBlob);
                    audioPlayer.src = audioUrl;
                    uploadButton.disabled = false;
                };
                mediaRecorder.start();
                startRecordButton.textContent = langlist['lang2'] + '...';
                audioPlayer.src = null;
                audioPlayer.load();
                startRecordButton.disabled = true;
                stopRecordButton.disabled = false;
                uploadButton.disabled = true;
                uploadButton.setAttribute('title', langlist['lang3']);
                clearInterval(timeid);
                timeid = setInterval(function () {
                    sec += 1;
                    startRecordButton.textContent = `${langlist['lang4']}${sec}s`;
                    // 大于20s强制停止
                    if (sec > 20) {
                        stopRecording();
                        clearInterval(timeid);
                    }
                }, 1000);

            })
            .catch(error => {
                console.error('getUserMedia error:', error);
            });
    }

    // 停止录音
    function stopRecording() {
        mediaRecorder.stop();
        startRecordButton.disabled = false;
        startRecordButton.textContent = langlist['lang5'];
        stopRecordButton.disabled = true;
        uploadButton.disabled = false;
        sec = 0;
        clearInterval(timeid);
    }

    // 录音后上传
    function uploadRecording() {
        const audioBlob = new Blob(audioChunks, {type: 'audio/wav'});

        const formData = new FormData();
        formData.append('audio', audioBlob, 'recorded_audio.wav');
        let index = layer.load();
        fetch('/upload', {
            method: 'POST',
            body: formData
        })
            .then(response => response.json())
            .then(data => {
                layer.close(index);
                console.log('Server response:', data);
                if (data['code'] == 0) {
                    let el = $('#audioSelect');
                    el.find('option[selected]').removeAttr('selected');
                    el.prepend('<option selected value="' + data['data'] + '">' + data['data'] + '</option>');
                    uploadButton.disabled = true;
                    uploadButton.setAttribute('title', langlist['lang6']);
                }
            })
            .catch(error => {
                layer.close(index);
                console.error('Upload error:', error);
            });
    }

    // 本地上传声音
    function uploadFromLocal(inputEl) {
        const fileInput = document.getElementById('fileInput');
        const selectedFile = fileInput.files[0];

        if (!selectedFile) {
            layer.alert(langlist['lang7'], {title: false});
            return;
        }

        const formData = new FormData();
        formData.append('audio', selectedFile);
        let index = layer.load();
        fetch('/upload', {
            method: 'POST',
            body: formData
        })
            .then(response => response.json())
            .then(data => {
                layer.close(index);
                if (data['code'] == 0) {
                    layer.msg('OK');
                    let el = $('#audioSelect');
                    el.find('option[selected]').removeAttr('selected');
                    el.prepend('<option selected value="' + data['data'] + '">' + data['data'] + '</option>');
                    let p = $(inputEl).parent();
                    $(inputEl).remove();
                    p.append(`<input id="fileInput" type="file" accept="audio/wav" class="position-absolute start-0 top-0 end-0 bottom-0 opacity-0" onchange="uploadFromLocal(this)" />`);
                } else {
                    layer.msg(data['msg'] ? data['msg'] : "Error", {icon: 2})
                }
            })
            .catch(error => {
                console.error('error:', error);
            });
    }

    // 上传srt
    function uploadsrt(el) {
        let textarea = document.getElementById('textInput')
        console.log(el.files[0])
        if (el.files[0]['name'].substr(-3).toLowerCase() != 'srt') {
            return layer.alert(langlist["lang8"], {title: false})
        }
        // 确保选择了文件
        if (el.files.length > 0) {
            const selectedFile = el.files[0];
            const reader = new FileReader();
            reader.onload = function (e) {
                // 将读取的内容写入 textarea
                textarea.value = e.target.result;
            };

            // 读取文件内容
            reader.readAsText(selectedFile);
        } else {
            layer.alert(langlist['lang9'], {title: false});
        }
    }


    // 初始化获取可用的声音列表
    function init() {
        $.get('/init', function (res) {
            console.log(res)
            if (res) {
                let html = '';
                res.forEach(it => {
                    html += '<option value="' + it + '">' + it + '</option>'
                })
                $('#audioSelect').html(html);
                $('#audioSelect2').html(html);
            }
        });
    }

    // 开始合成声音
    function start(el) {
        let voice = $("#audioSelect").val();
        let language = $('#languageSelect').val();
        let text = $('#textInput').val();
        // 当前所选的 合成类型
        let type = $('#tts-area').hasClass('d-none') ? 'sts' : 'tts';
        let speed = parseFloat($('#speed').val())
        let model=""
        // 如果 tts 判断模型有没有启动
        if(type==='tts'){
            model=$('#model').val();
            if(model !='default' && $(`[data-model-id="${model}"]`).data('status')!=='on'){
                layer.alert(language==='zh'?'该模型还没有启动，请启动后使用':'The model has not been launched yet, please launch it and use it',{title:false})
                return;
            }
        }
        if (type == 'tts' && !(speed > 0 && speed <= 2.0)) {
            layer.msg(langlist['lang16'])
            speed = 1.0
        }

        if (!voice) {
            return layer.alert(langlist['lang10'], {title: false});
        }
        if (type == 'tts' && !text) {
            return layer.alert(langlist['lang11'], {title: false});
        }
        if (type == 'sts' && !window['sts_audio_name']) {
            return layer.alert(langlist['lang12'], {title: false});
        }

        $('#tips').removeClass('d-none').text(langlist['lang13']);
        $(el).attr('disabled', 'disabled')
        window.timesec = 0;
        window.timeid = setInterval(function () {
            window.timesec += 1
            $('#tips').text(langlist['lang13'] + ':' + window.timesec + '秒')
        }, 1000);
        $("#downloadbtn").removeAttr('src').addClass('d-none');
        $("#downloadbtn")[0].load();
        $('#errors').html('');
        let fun_res = function (res) {
            $(el).removeAttr('disabled')
            window.timesec = 0;
            clearInterval(window.timeid);
            if (res.code !== 0) {
                $('#tips').text("Error：" + res.msg);
            } else {

                $("#downloadbtn").removeClass('d-none').attr('src', "/static/ttslist/" + res.name);
                if (res['msg']) {
                    $('#tips').html(res['msg']);
                } else {
                    $('#tips').addClass('d-none').text('');
                }

            }
        }

        if (type == 'tts') {
            $.post('/tts', {voice: voice, model:model,text: text, language: language, speed: speed}, function (res) {
                fun_res(res);
            });
        } else {
			voice = $("#audioSelect2").val();
            $.post('/sts', {voice: voice, name: window['sts_audio_name']}, function (res) {
                fun_res(res);
            });
        }
    }


    // 初始化 声音转声音
    function stsinit() {
        var dropaudio = $('#dropaudio');
        if (dropaudio.length < 1) {
            return
        }

        dropaudio.on('dragover', function (e) {
            e.preventDefault();
            dropaudio.addClass('dragover');
        });

        dropaudio.on('dragleave drop', function (e) {
            e.preventDefault();
            dropaudio.removeClass('dragover');
        });

        dropaudio.on('drop', function (e) {
            e.preventDefault();

            var files = e.originalEvent.dataTransfer.files;
            if (files.length > 0) {
                handleFileUpload(files[0]);
            }
        });

        dropaudio.on('click', function () {
            var fileInput = $('<input type="file" style="display: none;">');
            fileInput.on('change', function () {
                if (fileInput[0].files.length > 0) {
                    handleFileUpload(fileInput[0].files[0]);
                }
            });

            fileInput.click();
        });
    }
	
	function sts_status(){
		$.get('/stsstatus', function (res) {
            if (res.code === 0) {
				if(res.msg=='stop'){
					$('#sts_no').removeClass('d-none').text(language=='zh'?'声音转声音 线程未启动，如果已下载了模型，请打开 .env 文件将 ENABLE_STS=0 改为 ENABLE_STS=1，然后重启软件':'The sts model has not been launched yet, please download it and set .env  ENABLE_STS=0 to ENABLE_STS=1 ');
					if(!window.sts_time){
						window.sts_time=0;
					}
					window.sts_time+=5
					if(window.sts_time < 300){
						setTimeout(sts_status,5000);
					}
				}else{
					$('#sts_no').addClass('d-none').text("")
				}
            }
        });
	}


    // 拖拽上传声音音频  
    function handleFileUpload(file) {
        var dropaudio = $('#dropaudio');
        var formData = new FormData();
        formData.append('audio', file);
        formData.append('save_dir', 'tmp')
		let index=layer.load()
        $.ajax({
            type: 'POST',
            url: '/upload',  // Update with your backend endpoint
            data: formData,
            contentType: false,
            processData: false,
            success: function (response) {
                if (response.code === 0) {
                    oktext = file.name.substr(-3).toLowerCase() === 'wav' ? 'OK: ' : langlist['lang15']
                    dropaudio.text(oktext + response.data);
                    window['sts_audio_name'] = response.data
                } else {
                    dropaudio.text('Error: ' + response.msg);
                }
            },
            error: function () {
                dropaudio.text('Error');
            },
            beforeSend: function () {
                dropaudio.text(language==='zh'?'上传中请稍等..':'Uploading... ');
            },
            complete: function () {
				layer.close(index)
                dropaudio.removeClass('dragover');
            }
        });
    }

    function set_voice(el){
        let name=$(el).val();
        if(name!='default'){
            $('#audioSelect').prop('disabled',true);
            $('#startRecord').attr('disabled',true);
        }else{
            $('#startRecord').removeAttr('disabled');
            $('#audioSelect').prop('disabled',false);
        }
        if(name!='default' && $(`[data-model-id="${name}"]`).attr('data-status')!='on'){
            layer.alert(language==='zh'?'该模型还没有启动，请启动后使用':'The model has not been launched yet, please launch it and use it',{title:false})
            return
        }

    }
    // 核对自定义模型的启动和停止
    function check_start() {
        $.get('/isstart', function (res) {
            console.log(res)
            if(res && Object.keys(res).length>0){
                let html='';
                let select=`<option value="default">${language=='zh'?'默认':'default'}</option>`;
                for(let name in res){
                    html+=`<button data-model-id="${name}" class="btn btn-sm btn-outline-primary flex-grow-0" data-status="${res[name]?'on':'off'}" onclick="update_status('${name}',this)">${name}/${res[name]?langlist['lang19']:langlist['lang20']}</button>`;
                    select+=`<option value="${name}">${name}/${res[name]?langlist['lang19']:langlist['lang20']}</option>`;
                }
                $('#model_list').html(html);
                $('#model').html(select);
            }
        });
    }

    function checkupdate() {
        $.get('/checkupdate', function (res) {
            if (res.code === 0 && res.msg) {
                $('#checkupdate').removeClass('d-none').text(res.msg);
            }
        });
    }

    function showjz(el) {
        layer.open({
            type: 1, // page 层类型
            area: ['300px', '450px'],
            title: langlist['lang17'],
            shade: 0.6, // 遮罩透明度
            shadeClose: true, // 点击遮罩区域，关闭弹层
            maxmin: true, // 允许全屏最小化
            anim: 0, // 0-6 的动画形式，-1 不开启
            content: `<div style="padding: 10px; ">
			<div class="fs-6 text-black-500">${langlist['lang18']}</div>
			<img src="/static/images/wx.png" width="200px" style="display:block;margin:10px auto;">
			<img src="/static/images/alipay.png" width="200px" style="display:block;margin:10px auto">
			<img src="/static/images/mp.jpg" width="200px" style="display:block;margin:10px auto">
			</div>`
        });
    }
	

    init();
    stsinit();
    check_start();
    checkupdate();
    switch_language();
	{% if voice_model %}
		sts_status();
	{% endif %}

</script>

</body>
</html>